package com.siwei.mes.service.experiment.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.siwei.mes.common.query.PageQuery;
import com.siwei.mes.common.util.DateHelper;
import com.siwei.mes.common.util.JsonUtils;
import com.siwei.mes.entity.dto.OpenAppraisalDto;
import com.siwei.mes.entity.erp.*;
import com.siwei.mes.entity.experiment.Experiment;
import com.siwei.mes.entity.experiment.ExperimentDetail;
import com.siwei.mes.entity.experiment.OpenAppraisal;
import com.siwei.mes.entity.experiment.concrete.batch.ConcreteKyqd;
import com.siwei.mes.entity.mixproportion.MixProportion;
import com.siwei.mes.enums.CheckEnum;
import com.siwei.mes.enums.TestProjectEnum;
import com.siwei.mes.mapper.erp.ItemorderMapper;
import com.siwei.mes.mapper.erp.RwdextraExtendMapper;
import com.siwei.mes.mapper.erp.RwdextraMapper;
import com.siwei.mes.mapper.experiment.ExperimentDetailMapper;
import com.siwei.mes.mapper.experiment.ExperimentMapper;
import com.siwei.mes.mapper.experiment.OpenAppraisalMapper;
import com.siwei.mes.mapper.mixProportion.MixProportionMapper;
import com.siwei.mes.service.erp.RwdextraExtendService;
import com.siwei.mes.service.erp.RwdextraService;
import com.siwei.mes.service.experiment.OpenAppraisalService;
import com.siwei.mes.sync.erp.entity.ItemorderFinish;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

import static com.siwei.mes.common.exception.handler.MessageHandler.assertTrue;

/**
 * 开盘鉴定表(OpenAppraisal)表服务实现类
 *
 * @author yangke
 * @since 2024-11-23 10:50:05
 */
@Slf4j
@Service
public class OpenAppraisalServiceImpl implements OpenAppraisalService {
    @Resource
    private OpenAppraisalMapper openAppraisalMapper;
    @Resource
    private RwdextraExtendMapper rwdextraExtendMapper;
    @Resource
    private ItemorderMapper itemorderMapper;
    @Resource
    private ExperimentMapper experimentMapper;
    @Resource
    private RwdextraMapper rwdextraMapper;
    @Resource
    private MixProportionMapper mixProportionMapper;
    @Resource
    private ExperimentDetailMapper experimentDetailMapper;
    @Resource
    private RwdextraExtendService rwdextraExtendService;
    @Resource
    private RwdextraService rwdextraService;

    @Override
    public void hasOpenAppraisal(Rwdextra rwdextra, ItemorderFinish itemorderFinish, Boolean isUpdate) {
        try {
            /**根据年份、工程名称、配合比编号查询是否有符合条件的开盘鉴定 **/
            RwdextraInfo rwdextraInfo = rwdextra.getRwdextraInfo();
            String year = String.valueOf(DateHelper.getYear());
            String projectName = itemorderFinish.getProjectName();
            String proportionPhb = rwdextra.getPhbshow();
            if (StringUtils.isBlank(proportionPhb)) {
                log.error("保存任务单开盘鉴定json数据失败，任务单没有配合比信息： 任务单号【{}】", rwdextra.getFrwdh());
                return;
            }
            OpenAppraisal entity = openAppraisalMapper.selectByItemOrder(year, projectName, proportionPhb);
            if (entity == null) {
                entity = new OpenAppraisal();
                entity.init(true);
                entity.setCreateTime(rwdextra.getPlantime());
                entity.setFrwdh(rwdextra.getFrwdh());
                entity.setFrwno(rwdextraInfo.getFRwno());
                entity.setCarNo(itemorderFinish.getCarNumber());
                /** todo 目前小票里没有车牌信息
                 entity.setCarCard();**/
                entity.setYear(year);
                entity.setProjectName(projectName);
                entity.setProportionPhb(proportionPhb);
                /**保存开盘鉴定扩展表对应打印信息**/
                JSONObject printJson = rwdextra.getRwdextraExtend().getPrintJson();
                RwdextraPrintInfo rwdextraPrintInfo = JsonUtils.getObject(printJson, RwdextraPrintInfo.class);
                entity.setPrintJson(JsonUtils.beanToObject(rwdextraPrintInfo));
                openAppraisalMapper.insertSelective(entity);
            } else {
                /**如果是修改需要支持修改数据*/
                if (isUpdate) {
                    /**保存开盘鉴定扩展表对应打印信息**/
                    JSONObject printJson = rwdextra.getRwdextraExtend().getPrintJson();
                    RwdextraPrintInfo rwdextraPrintInfo = JsonUtils.getObject(printJson, RwdextraPrintInfo.class);
                    entity.setPrintJson(JsonUtils.beanToObject(rwdextraPrintInfo));
                    openAppraisalMapper.updateByPrimaryKeySelective(entity);
                }
                initOpenAppraisalPhb(entity);
            }
            /**更新任务单开盘鉴定编号**/
            RwdextraExtend rwdextraExtend = rwdextraExtendMapper.selectByFRwdh(rwdextra.getFrwdh());
            rwdextraExtend.setOpenAppraisalId(entity.getId());
            rwdextraExtendMapper.updateByPrimaryKeySelective(rwdextraExtend);
        } catch (Exception e) {
            log.error("保存任务单开盘鉴定json数据失败，错误信息：【{}】", e.getMessage(), e);
        }
    }

    @Override
    public Long create(OpenAppraisal entity) {
        openAppraisalMapper.insertSelective(entity);
        return entity.getId();
    }

    @Override
    public void update(OpenAppraisal entity) {
        OpenAppraisal openAppraisal = openAppraisalMapper.selectByPrimaryKey(entity.getId());
        assertTrue(openAppraisal == null, "开盘鉴定表信息不存在");
        openAppraisalMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public void delete(Long id) {
        OpenAppraisal openAppraisal = openAppraisalMapper.selectByPrimaryKey(id);
        assertTrue(openAppraisal == null, "开盘鉴定表信息不存在");
        openAppraisalMapper.deleteByPrimaryKey(id);
    }

    @Override
    public PageInfo<OpenAppraisal> getPage(PageQuery<OpenAppraisal, OpenAppraisal> query) {
        OpenAppraisal searchParam = query.getParams();
        PageInfo<OpenAppraisal> pageInfo = PageHelper.startPage(query.getPageNum(), query.getPageSize())
                .doSelectPageInfo(() -> openAppraisalMapper.getList(searchParam));
        for (OpenAppraisal openAppraisal : pageInfo.getList()) {
            if (openAppraisal.getPrintJson() != null) {
                RwdextraPrintInfo rwdextraPrintInfo = JsonUtils.getObject(openAppraisal.getPrintJson(), RwdextraPrintInfo.class);
                openAppraisal.setRwdextraPrintInfo(rwdextraPrintInfo);
            }
            Rwdextra rwdextra = rwdextraService.selectByFrwdh(openAppraisal.getFrwdh());
            if (rwdextra != null) {
                openAppraisal.setRwdextra(rwdextra);
            }
        }
        return pageInfo;
    }

    @Override
    public OpenAppraisal loadById(Long id) {
        return openAppraisalMapper.loadById(id);
    }

    @Override
    public Long loadKyExperimentById(Long id) {
        OpenAppraisal openAppraisal = openAppraisalMapper.loadById(id);
        RwdextraPrintInfo rwdextraPrintInfo = JsonUtils.getObject(openAppraisal.getPrintJson(), RwdextraPrintInfo.class);
        if (rwdextraPrintInfo != null) {
            List<RwdextraPrintInfo.Kytz> kyInfoList = rwdextraPrintInfo.getKyInfoList();
            if (CollectionUtil.isNotEmpty(kyInfoList)) {
                RwdextraPrintInfo.Kytz kyInfo = kyInfoList.get(0);
                if (StringUtils.isNotBlank(kyInfo.getSytzbh())) {
                    return Long.valueOf(kyInfo.getSytzbh());
                }
            }
        }
        return null;
    }

    @Override
    public List<OpenAppraisal> getAll(OpenAppraisal entity) {
        return openAppraisalMapper.getList(entity);
    }

    @Override
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void updateOpenAppraisalPhb() {
        List<OpenAppraisal> openAppraisalList = openAppraisalMapper.getList(new OpenAppraisal());
        for (OpenAppraisal openAppraisal : openAppraisalList) {
            Rwdextra rwdextra = rwdextraMapper.selectByFrwdh(openAppraisal.getFrwdh());
            RwdextraPrintInfo rwdextraPrintInfo = JsonUtils.getObject(openAppraisal.getPrintJson(), RwdextraPrintInfo.class);
            if (rwdextraPrintInfo != null) {
                MixProportion mixProportion = rwdextraPrintInfo.getMixProportionInfo();
                rwdextraExtendService.setMixProportionPktzId(mixProportion, rwdextra);
                rwdextraPrintInfo.setMixProportionInfo(mixProportion);
                openAppraisal.setPrintJson(JsonUtils.beanToObject(rwdextraPrintInfo));
                openAppraisalMapper.updateByPrimaryKeySelective(openAppraisal);
            }
        }
    }

    @Override
    public void cleanOpenAppraisal() {
        /** 分组查询所有 不同工程 配合比 年份的数据 **/
        List<OpenAppraisalDto> openAppraisalDtoList = rwdextraMapper.selectOpenAppraisalByRwd();
        for (OpenAppraisalDto dto : openAppraisalDtoList) {
            /** 生成开盘鉴定**/
            OpenAppraisal entity = initOpenAppraisal(dto);
            /** 绑定任务单**/
            if (entity != null) {
                String year = dto.getFrwno();
                String projectName = dto.getFgcmc();
                String proportionPhb = dto.getFphbNo();
                rwdextraExtendMapper.updateByPhbYearProject(entity.getId(), proportionPhb, projectName, year);
            }
        }
    }


    @Override
    public OpenAppraisal initOpenAppraisal(OpenAppraisalDto dto) {
        /** 生成开盘鉴定**/
        OpenAppraisal entity = new OpenAppraisal();
        entity.init(true);
        String year = dto.getFrwno();
        String projectName = dto.getFgcmc();
        String proportionPhb = dto.getFphbNo();
        entity.setYear(year);
        entity.setProjectName(projectName);
        entity.setProportionPhb(proportionPhb);
        /** 根据工程 配合比 年份 查询时间最早的任务单信息 **/
        Rwdextra rwdextra = rwdextraService.selectByPhbTop(proportionPhb, projectName, year);

        if (rwdextra == null) {
            log.info("重新生产开盘鉴定信息任务单信息不存在 配合比【{}】 工程【{}】 年份【{}】", proportionPhb, projectName, year);
            return null;
        }
        Integer frwdh = rwdextra.getFrwdh();
        RwdextraInfo rwdextraInfo = rwdextra.getRwdextraInfo();
        /** todo 目前小票里没有车牌信息
         * entity.setCarCard();**/
        entity.setCreateTime(rwdextra.getPlantime());
        entity.setFrwdh(rwdextra.getFrwdh());
        entity.setFrwno(rwdextraInfo.getFRwno());
        Itemorder itemorder = itemorderMapper.selectByFrwdhTop(frwdh);
        if (itemorder != null) {
            entity.setCarNo(itemorder.getCarnumber());
        }
        /** 绑定对应的配合比信息**/
        RwdextraPrintInfo rwdextraPrintInfo = new RwdextraPrintInfo();
        MixProportion mixProportion = mixProportionMapper.selectByPhbNo(proportionPhb);
        if (mixProportion == null) {
            log.info("重新生产开盘鉴定信息 配合比编号不存在 【{}】", proportionPhb);
            return null;
        }
        rwdextraExtendService.setMixProportionPktzId(mixProportion, rwdextra);
        rwdextraPrintInfo.setMixProportionInfo(mixProportion);
        /**重新查询所有关联的实验台账进行赋值**/
        /** 抗压 存在多个**/
        List<Long> kyExperimentIdList = experimentDetailMapper.selectExperimentIdByTestProjectCode(frwdh, CheckEnum.BATCH.getCode(), TestProjectEnum.CONCRETE_PARAM_KYQD.getCode());
        if (!kyExperimentIdList.isEmpty()) {
            List<String> kytzList = new ArrayList();
            List<RwdextraPrintInfo.Kytz> kyInfoList = new ArrayList();
            for (Long experimentId : kyExperimentIdList) {
                RwdextraPrintInfo.Kytz kytz = new RwdextraPrintInfo.Kytz();
                Experiment experiment = experimentMapper.loadById(experimentId);
                if (experiment != null) {
                    if (StringUtils.isNotBlank(experiment.getSampleId())) {
                        kytzList.add(experiment.getSampleId());
                    } else {
                        kytzList.add(experiment.getExperimentNo());
                    }
                    kytz.setWtbh(experiment.getExperimentNo());
                    kytz.setXhwtbh(experiment.getConsignId());
                    kytz.setYpbh(experiment.getSampleId());
                    kytz.setSytzbh(String.valueOf(experiment.getId()));
                    List<ExperimentDetail> experimentDetailList = experimentDetailMapper.selectByExperimentId(experimentId, TestProjectEnum.CONCRETE_PARAM_KYQD.getCode());
                    if (CollectionUtil.isNotEmpty(experimentDetailList)) {
                        /**将json转成对象*/
                        ConcreteKyqd concreteKyqd = experimentDetailList.get(0).getObjJson().toJavaObject(ConcreteKyqd.class);
                        kytz.setQdpjz(concreteKyqd.getPjz28d());
                        kytz.setDdsjqd(concreteKyqd.getFyxs28d());
                        kytz.setZsbzqd(concreteKyqd.getZsbzqd28d());
                    }
                    kyInfoList.add(kytz);
                }
                rwdextraPrintInfo.setKytzList(kytzList);
                rwdextraPrintInfo.setKyInfoList(kyInfoList);
            }
        }
        /** 抗渗 只取一个 默认取计划时间最近一次试验台账**/
        List<Long> ksExperimentIdList = experimentDetailMapper.selectExperimentIdByTestProjectCode(frwdh, CheckEnum.BATCH.getCode(), TestProjectEnum.CONCRETE_PARAM_KSDJ.getCode());
        if (!ksExperimentIdList.isEmpty()) {
            rwdextraPrintInfo.setKsExperimentId(ksExperimentIdList.get(0));
        }
        /** 抗折 只取一个 默认取计划时间最近一次试验台账**/
        List<Long> kzExperimentIdList = experimentDetailMapper.selectExperimentIdByTestProjectCode(frwdh, CheckEnum.BATCH.getCode(), TestProjectEnum.CONCRETE_PARAM_KZQD.getCode());
        if (!kzExperimentIdList.isEmpty()) {
            rwdextraPrintInfo.setKzExperimentId(kzExperimentIdList.get(0));
        }
        /** 抗氯离子 只取一个 默认取计划时间最近一次试验台账**/
        List<Long> kllzExperimentIdList = experimentDetailMapper.selectExperimentIdByTestProjectCode(frwdh, CheckEnum.BATCH.getCode(), TestProjectEnum.CONCRETE_PARAM_XNBG_LLZHL.getCode());
        if (!kllzExperimentIdList.isEmpty()) {
            log.info("存在氯离子绑定台账的任务单【{}】", frwdh);
            rwdextraPrintInfo.setKllExperimentId(kllzExperimentIdList.get(0));
        } else {
            kllzExperimentIdList = experimentDetailMapper.selectExperimentIdByTestProjectCodeRwd(TestProjectEnum.CONCRETE_PARAM_XNBG_LLZHL.getCode(), proportionPhb, projectName, year);
            if (!kllzExperimentIdList.isEmpty()) {
                rwdextraPrintInfo.setKllExperimentId(kllzExperimentIdList.get(0));
                log.info("不存在氯离子绑定台账的任务单【{}】 关联绑定试验台账ID :【{}】", frwdh, kllzExperimentIdList);
            } else {
                log.info("不存在氯离子绑定台账的任务单【{}】 ", frwdh, kllzExperimentIdList);
            }
        }
        entity.setPrintJson(JsonUtils.beanToObject(rwdextraPrintInfo));
        /** 补充逻辑 如果任务单扩展表配合比信息为空 补充对应信息更新 **/
        RwdextraExtend rwdextraExtend = rwdextra.getRwdextraExtend();
        if (rwdextraExtend != null) {
            RwdextraPrintInfo rwdextraPrintInfoExtend = JsonUtils.getObject(rwdextraExtend.getPrintJson(), RwdextraPrintInfo.class);
            if (rwdextraPrintInfoExtend == null) {
                rwdextraPrintInfoExtend = rwdextraPrintInfo;
                rwdextraExtend.setPrintJson(JsonUtils.beanToObject(rwdextraPrintInfoExtend));
                rwdextraExtendMapper.updateByPrimaryKeySelective(rwdextraExtend);
            }
        }
        openAppraisalMapper.insertSelective(entity);
        return entity;
    }

    @Override
    public void initOpenAppraisalPhb(OpenAppraisal entity) {
        /** 判断是否存在配合比信息，如果不存在更新配比信息 **/
        RwdextraPrintInfo rwdextraPrintInfo = JsonUtils.getObject(entity.getPrintJson(), RwdextraPrintInfo.class);
        if (rwdextraPrintInfo == null) {
            log.info("开盘鉴定更新配比信息 ERP任务单扩展信息打印修改记录不存在 开盘鉴定编号【{}】 ", entity.getAppraisalNo());
            return;
        }
        MixProportion mixProportion = rwdextraPrintInfo.getMixProportionInfo();
        if (mixProportion == null) {
            log.info("开盘鉴定更新配比信息 开盘鉴定不存在配合比信息 开盘鉴定编号【{}】 ", entity.getAppraisalNo());
            if (entity.getFrwdh() != null) {
                Rwdextra rwdextra = rwdextraMapper.selectByFrwdh(entity.getFrwdh());
                if (StringUtils.isNotBlank(rwdextra.getFphbNo())) {
                    MixProportion mixProportionNew = mixProportionMapper.selectByPhbNo(rwdextra.getFphbNo());
                    rwdextraExtendService.setMixProportionPktzId(mixProportionNew, rwdextra);
                    rwdextraPrintInfo.setMixProportionInfo(mixProportionNew);
                    entity.setPrintJson(JsonUtils.beanToObject(rwdextraPrintInfo));
                    openAppraisalMapper.updateByPrimaryKeySelective(entity);
                } else {
                    log.info("开盘鉴定更新配比信息 任务单不存在配合比信息 开盘鉴定编号【{}】 任务单号 【{}】", entity.getAppraisalNo(), entity.getFrwdh());
                }
            }
        }
    }
}
